package com.eth.wallet.web3j.account;

import com.eth.wallet.exception.AccountException;
import com.eth.wallet.exception.ExceptionCode;
import org.springframework.util.ResourceUtils;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Keys;
import org.web3j.crypto.WalletUtils;
import org.web3j.utils.Numeric;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/**
 * 账号相关帮助类
 * Created by Niki on 2018/12/16 12:26
 */
public class AccountUtil {

    /**
     * keystore生成的目录
     */
    private static File KEYSTORE_FILE_DIR;

    static {
        try {
            KEYSTORE_FILE_DIR = ResourceUtils.getFile("classpath:keystore");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成账号
     *
     * @return 返回账号的私钥
     */
    public static String createAccount() {
        try {
            ECKeyPair ecKeyPair = Keys.createEcKeyPair();
            BigInteger prikey = ecKeyPair.getPrivateKey();
            return Numeric.toHexStringNoPrefix(prikey);

        } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new AccountException(ExceptionCode.ACCOUNT_CREATE_ERROR.getMsg());
        }
    }

    /**
     * 创建账号，并导出keystore
     * @param privateKey 账号私钥
     * @param password 解密keystore的密码
     * @return keystore文件路径
     */
    public static String createAccountKeyStore(String privateKey, String password) {
        ECKeyPair ecKeyPair = priKeyToECKeyPair(privateKey);
        try {
            return WalletUtils.generateWalletFile(password, ecKeyPair, KEYSTORE_FILE_DIR, true);
        } catch (CipherException | IOException e) {
            throw new AccountException(ExceptionCode.ACCOUNT_KEYSTORE_ERROR.getMsg());
        }
    }

    /**
     * 创建账号keystore文件
     * @param privateKey 私钥
     * @param password 解密keystore文件密码
     * @return keystore文件流
     */
    public static FileOutputStream createAccountKeyStoreStream(String privateKey, String password) {
        String filePath = createAccountKeyStore(privateKey, password);
        try {
            return new FileOutputStream(filePath);
        } catch (FileNotFoundException e) {
            throw new AccountException(ExceptionCode.ACCOUNT_KEYSTORE_ERROR.getMsg());
        }
    }


    /**
     * 根据私钥获取公钥
     *
     * @param privateKey 私钥
     * @return 公钥
     */
    public static String priKeyToPubKey(String privateKey) {
        ECKeyPair ecKeyPair = ECKeyPair.create(privateKey.getBytes());
        BigInteger pubKeyInt = ecKeyPair.getPublicKey();
        return Numeric.toHexStringNoPrefix(pubKeyInt);
    }

    /**
     * 根据私钥计算出账号的地址
     *
     * @param privateKey 私钥
     * @return 地址
     */
    public static String priKeyToAddress(String privateKey) {
        String pubKey = priKeyToPubKey(privateKey);
        return Keys.getAddress(pubKey);
    }

    /**
     * 根据私钥获得ECKeyPair
     *
     * @param privateKey 私钥
     * @return ECKeyPair
     */
    public static ECKeyPair priKeyToECKeyPair(String privateKey) {
        return ECKeyPair.create(privateKey.getBytes());
    }
}
